package com.congee02.dbservlet.framework.orm;

import lombok.SneakyThrows;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 将查找到的 ResultSet 转为集合，在 {@link ResultSetConverter} 中将每行数据转为对象
 */
public final class ResultSetConverter<T> {

    /**
     * 映射到数据库表的实体类字节码对象
     */
    private final Class<T> tableEntityClazz;

    private final Set<Map.Entry<String, Field>> columnFieldEntries;

    private final ReentrantLock lock = new ReentrantLock();

    public ResultSetConverter(Class<T> tableEntityClazz) {
        this.tableEntityClazz = tableEntityClazz;
        this.columnFieldEntries = Column2FieldUtils.columnFieldMap(tableEntityClazz).entrySet();
    }

    @SneakyThrows
    public List<T> convert(ResultSet rs) {
        lock.lock();
        List<T> result = new ArrayList<>();
        try {
            while (rs.next()) {
                T instance = tableEntityClazz.getConstructor().newInstance();
                for (Map.Entry<String, Field> e : columnFieldEntries) {
                    Field field = e.getValue();
                    String column = e.getKey();
                    field.setAccessible(true);
                    field.set(instance, rs.getObject(column));
                    field.setAccessible(false);
                }
                result.add(instance);
            }
        } finally {
            lock.unlock();
        }
        return result;
    }

}
